#include "GUIMenuItem.h"
#include "IRenderer.h"
#include "OnMouseLeftDownEvent.h"
#include "OnMouseLeftUpEvent.h"

#define PADDING				2
#define OBJECTWIDTH			80
#define OBJECTHEIGHT		10
#define OBJECTHEIGHTOFFSET	(OBJECTHEIGHT-12)/2
#define INDENT				10

GUIMenuItem::GUIMenuItem() : m_totalHeight(0), m_totalWidth(0), m_isOpen(false), m_textHeight(0)
{
	m_fontColor = 0x00000000;
	m_font = HashedString("Arial");
	m_visible = true;
	m_enabled = true;
	m_dimensions = Maths::Point<unsigned int>(OBJECTWIDTH, OBJECTHEIGHT);
}
void GUIMenuItem::CalculateHeight()
{
	int height = 0;	// init to 0

	for (IGUIElement::Vector_t::const_iterator it = m_elements.begin(); it != m_elements.end(); ++it)
	{
		int temp = (*it)->Location().Y + (*it)->Dimensions().Y + 2;

		if (temp > height)
			height = temp;
	}
	m_totalHeight = height;
}
void GUIMenuItem::CalculateWidth()
{
	int width = 0;	

	for (IGUIElement::Vector_t::const_iterator it = m_elements.begin(); it != m_elements.end(); ++it)
	{
		int temp = (*it)->Location().X + (*it)->Dimensions().X;

		if (temp > width)
			width = temp;
	}
	m_totalWidth = width;
}
void GUIMenuItem::TextHeight( unsigned int textHeight )
{
	m_textHeight = textHeight;
}
void GUIMenuItem::Paint()
{
	if (m_visible)
	{
		// Render Background
		Maths::Matrix transform;
		transform.Translate(m_location.X, m_location.Y, 0.0f);
		transform.Scale(m_dimensions.X, m_dimensions.Y, 1.0f);
		
		Renderer->SetColor(0xFFDDDDDD);
		Renderer->PushTexture(m_background);
		Renderer->PushModelViewMatrix(transform);
		Renderer->Render(*(m_shape.getShape()));
		Renderer->PopModelViewMatrix();
		Renderer->PopTexture();

		// Render title
		Renderer->PrintFont(m_font, m_fontColor, m_parentLocation.X + m_location.X + 4, m_parentLocation.Y + m_location.Y + OBJECTHEIGHTOFFSET, m_title.c_str());

		// Render Children Elements
		if (m_isOpen)
		{
			transform.Identity();
			transform.Translate(m_location.X, m_location.Y + OBJECTHEIGHT, 0.0f);
			Renderer->PushModelViewMatrix(transform);

			for (IGUIElement::Vector_t::const_iterator it = m_elements.begin(); it != m_elements.end(); ++it)
				(*it)->Paint();

			Renderer->PopModelViewMatrix();
		}
	}
}
void GUIMenuItem::Location( Maths::Point<unsigned int>& location )
{
	IGUIElement::Location(location);
	for (IGUIElement::Vector_t::const_iterator it = m_elements.begin(); it != m_elements.end(); ++it)
		(*it)->ParentLocation(Maths::Point<unsigned int>(m_location.X + m_parentLocation.X, m_location.Y + m_parentLocation.Y + OBJECTHEIGHT));
}
void GUIMenuItem::Title( std::string& title )
{
	m_title = title;
}
std::string GUIMenuItem::Title() const
{
	return m_title;
}
void GUIMenuItem::Font( std::string& font )
{
	m_font = HashedString(font);
}
void GUIMenuItem::Font( HashedString& font )
{
	m_font = font;
}
HashedString GUIMenuItem::Font() const
{
	return m_font;
}
void GUIMenuItem::FontColor( unsigned int color )
{
	m_fontColor = color;
}
unsigned int GUIMenuItem::FontColor() const
{
	return m_fontColor;
}
void GUIMenuItem::Background( std::string& background )
{
	m_background = HashedString(background);
}
void GUIMenuItem::Background( HashedString& background )
{
	m_background = background;
}
HashedString GUIMenuItem::Background() const
{
	return m_background;
}
void GUIMenuItem::Open( bool open )
{
	m_isOpen = open;
}
bool GUIMenuItem::Open() const
{
	return m_isOpen;
}
bool GUIMenuItem::ReceiveEvent( IEvent& event )
{
	if (event.Type() == OnMouseLeftDownEvent::type)
	{
		OnMouseLeftDownEvent& mouseEvent = static_cast<OnMouseLeftDownEvent&>(event);
		int x = mouseEvent.Coords().X;
		int y = mouseEvent.Coords().Y;
		int absX = m_location.X + m_parentLocation.X;
		int absY = m_location.Y + m_parentLocation.Y;
		
		if ((x > absX) && (x < absX + OBJECTWIDTH) &&
			(y > absY) && (y < absY + OBJECTHEIGHT))						// title clicked
		{
			m_isOpen = !m_isOpen;
			return true;
		} else if (m_isOpen &&												// Only pass events if open
				  (x > absX) && (x < absX + m_totalWidth) &&
				  (y > absY + OBJECTHEIGHT) && (y < absY + OBJECTHEIGHT + m_totalHeight))	// open body clicked
		{
			for (IGUIElement::Vector_t::iterator it = m_elements.begin(); it != m_elements.end(); ++it)
			{
				if ((*it)->ReceiveEvent(event))
					return true;
			}
		}
	}else if (event.Type() == OnMouseLeftUpEvent::type)
	{
		OnMouseLeftUpEvent& mouseEvent = static_cast<OnMouseLeftUpEvent&>(event);
		int x = mouseEvent.Coords().X;
		int y = mouseEvent.Coords().Y;
		int absX = m_location.X + m_parentLocation.X;
		int absY = m_location.Y + m_parentLocation.Y + OBJECTHEIGHT;
		if (m_isOpen &&												// Only pass events if open
			(x > absX) && (x < absX + m_totalWidth) &&
			(y > absY) && (y < absY + m_totalHeight))	// open body clicked
		{
			for (IGUIElement::Vector_t::iterator it = m_elements.begin(); it != m_elements.end(); ++it)
			{
				if ((*it)->ReceiveEvent(event))
					return true;
			}
		}
	}
	return false;
}
void GUIMenuItem::AddElement( Pointer<IGUIElement> element )
{
	m_elements.push_back(element);
	element->ParentLocation(Maths::Point<unsigned int>(m_location.X + m_parentLocation.X, m_location.Y + m_parentLocation.Y + OBJECTHEIGHT));
	element->Parent(this);
	CalculateHeight();
	CalculateWidth();
}
unsigned int GUIMenuItem::TotalHeight() const
{
	return m_totalHeight;
}
unsigned int GUIMenuItem::TotalWidth() const
{
	return m_totalWidth;
}